using System;
using System.Collections.Generic;
using System.Reflection;
using CodeStory.Core.Attributes;
using CodeStory.Core.ObjectEntity;

namespace CodeStory.Core.Authentication
{
	public static class DescriptorService
	{
		private static Dictionary<string, Descriptor> dict;

		static DescriptorService() {
			dict = new Dictionary<string, Descriptor>(8);
		}

		public static Descriptor GetDescriptor(string name) {
			Descriptor desc = null;
			if (dict.ContainsKey(name)) {
				desc = dict[name];
			} else {
				PermissionDescriptorObject obj = PermissionDescriptorObject.ReadUsingUniqueField("ResourceType", name);
				string actionTypeString = obj.ActionType;
				Type actionType = Type.GetType(actionTypeString);
				Array values = Enum.GetValues(actionType);
				desc = new Descriptor();
				desc.Name = name;
				foreach (Enum v in values) {
					string vstr = v.ToString();
					FieldInfo fieldInfo = v.GetType().GetField(vstr);
					PermissionDescriptionAttribute attr = (PermissionDescriptionAttribute)Attribute.GetCustomAttribute(fieldInfo, typeof(PermissionDescriptionAttribute));
					if (attr != null) {
						ActionDescriptor d = new ActionDescriptor();
						d.Position = (int)Enum.Parse(actionType, vstr);
						d.Description = attr.Description;
						desc.List.Add(d);
					} else {
						ActionDescriptor d = new ActionDescriptor();
						d.Position = (int)Enum.Parse(actionType, vstr);
						d.Description = fieldInfo.Name;
						desc.List.Add(d);
					}
				}
				dict[name] = desc;
			}
			return desc;
		}
	}

	public class Descriptor
	{
		private string name = "";
		private List<ActionDescriptor> list;

		public Descriptor() {
			list = new List<ActionDescriptor>();
		}

		public List<ActionDescriptor> List {
			get { return list; }
		}
		public string Name {
			get { return name; }
			set { name = value; }
		}
	}

	public class ActionDescriptor
	{
		private int position = -1;
		private string description = string.Empty;
		public int Position {
			get { return position; }
			set { position = value; }
		}
		public string Description {
			get { return description; }
			set { description = value; }
		}
	}
}